package com.fansl.allround.daemon.quartz.listener;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fansl.allround.common.core.constant.enums.ScheduleJobStatusEnum;
import com.fansl.allround.daemon.quartz.entity.ScheduleJob;
import com.fansl.allround.daemon.quartz.service.ScheduleJobService;
import com.fansl.allround.daemon.quartz.util.ScheduleJobUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * @author fansl
 * @Description: TODO
 * @date 2020/1/10 15:29
 */
@Slf4j
@Component
public class StartApplicationListener implements ApplicationRunner {
    @Autowired
    private ScheduleJobService scheduleJobService;
    @Autowired
    private Scheduler scheduler;

    @Override
    public void run(ApplicationArguments arguments) throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("初始化分布式任务[开始]");
        }
        List<ScheduleJob> scheduleJobs = scheduleJobService.list(Wrappers.<ScheduleJob>lambdaQuery().ne(ScheduleJob::getStatus,ScheduleJobStatusEnum.COMPLETED));
        scheduleJobs.stream().forEach(scheduleJob -> {
            if (isValidExpression(scheduleJob.getCronExpression())) {
                log.info("初始化分布式任务[开始]，jobId:{}", scheduleJob.getJobId());
                CronTrigger cronTrigger = ScheduleJobUtil.getCronTrigger(scheduler, scheduleJob.getJobId(), scheduleJob.getJobGroup());
                //如果不存在，则创建
                if (ObjectUtil.isNull(cronTrigger)) {
                    ScheduleJobUtil.createScheduleJob(scheduler, scheduleJob);
                } else {
                    ScheduleJobUtil.updateScheduleJob(scheduler, scheduleJob);
                }
            }
        });
        if (log.isDebugEnabled()) {
            log.debug("初始化分布式任务[结束]");
        }
    }

    public static boolean isValidExpression(final String cronExpression) {
        CronTriggerImpl trigger = new CronTriggerImpl();
        try {
            trigger.setCronExpression(cronExpression);
            Date date = trigger.computeFirstFireTime(null);
            return date != null && date.after(new Date());
        } catch (Exception e) {
            log.error("isValidExpression:failed. throw ex:", e);
        }
        return false;
    }
}
